﻿#include "stdafx.h"
#include "mgTexture.h"
#include "base/mgImage.h"
#include "main_data_c.h"
#include "ui/msgbox.h"

namespace mg
{
	Texture::Texture()
	{
		m_textureId = -1;
		m_target = GL_TEXTURE_2D;
		m_width = 0;
		m_height = 0;
		m_data = NULL;
	}

	Texture::~Texture()
	{
		if (m_textureId != -1) {
			glDeleteTextures(1, &m_textureId);
			m_textureId = -1;
		}
		if (m_data) {
			delete[] m_data;
			m_data = NULL;
		}
	}

	bool Texture::load(const char* filename, int desired_channels, bool powerOfTwo, bool make_mipmaps, GLuint texId, GLenum target)
	{
		if (m_textureId != -1) return false;

		Image img;
		if (img.load(filename, desired_channels)) {
			m_channels = img.getChannels();
			int fmt;
			switch (m_channels)
			{
			case 3:
				fmt = GL_RGB;
				break;
			case 4:
				fmt = GL_RGBA;
				break;
			default:
				return false;
			}

			if (texId != -1) {
				m_textureId = texId;
			}
			else {
				glGenTextures(1, &m_textureId);
			}
			m_target = target;
			m_width = img.getWidth();
			m_height = img.getHeight();
			BYTE* data = img.getData();

			if (powerOfTwo) {
				m_data = convertPowerOfTwo(data, m_channels, m_width, m_height);
			}
			if (!m_data) {
				int dataSize = img.getDataSize();
				m_data = new BYTE[dataSize];
				memcpy(m_data, data, dataSize);
			}
			glBindTexture(m_target, texId);
			glTexImage2D(m_target, 0, fmt, m_width, m_height, 0, fmt, GL_UNSIGNED_BYTE, m_data);
			glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

			return true;
		}
		return false;
	}

	void Texture::bind(int unit)
	{
		//glActiveTexture(0);
		glBindTexture(m_target, m_textureId);
	}

	GLuint Texture::detachTextureId(BYTE*& outData)
	{
		GLuint texId = m_textureId;
		m_textureId = -1;
		outData = m_data;
		m_data = NULL;
		return texId;
	}

	void Texture::TexParameter(GLuint mag_filter, GLuint min_filter, GLuint wrap_s, GLuint wrap_t)
	{
		bind(0);
		glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, mag_filter);
		glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, min_filter);
		glTexParameteri(m_target, GL_TEXTURE_WRAP_S, wrap_s);
		glTexParameteri(m_target, GL_TEXTURE_WRAP_T, wrap_t);
	}

	BYTE* Texture::convertPowerOfTwo(BYTE* data, int channels, int& width, int& height)
	{
		int outW = 1;
		int outH = 1;

		if (width > 256 || height > 256) {
			return false;
		}

		while (outW < width) outW <<= 1;

		while (outH < height) outH <<= 1;

		if (outW != width || outH != height) {
			int dstLineSize = outW * channels;
			int dataSize = dstLineSize * outH;
			int srcLineSize = width * channels;
			BYTE* outData = new BYTE[dataSize];
			BYTE* pOutData = outData;

			memset(outData, 0, dataSize);
			for (size_t i = 0; i < height; i++)
			{
				memcpy(pOutData, data, srcLineSize);
				pOutData += dstLineSize;
				data += srcLineSize;
			}
			width = outW;
			height = outH;
			return outData;
		}
		return NULL;
	}

}

bool LoadTexture(const char* filepath, int texId, int filter, int wrap)
{
	mg::Texture tex;
	if (tex.load(filepath, 0, true, false, texId)) {
		tex.TexParameter(filter, filter, wrap, wrap);
		TextureDataInfo* texInfo = mainData.texDataInfo_81C49B0 + texId;
		texInfo->width = tex.getWidth();
		texInfo->height = tex.getHeight();
		texInfo->channels = tex.getChannels();
		texInfo->name[0] = 0;
		tex.detachTextureId(texInfo->data);
		int dataSize = texInfo->width * texInfo->height * texInfo->channels;
		mainData.texDataByteCount_81D3D70 += dataSize;
		return true;
	}
	return false;
}

/*
  加载jpg图片，创建纹理

  filepath 文件路径
  texId textureId
  filter GL_TEXTURE_MAG_FILTER GL_TEXTURE_MIN_FILTER
  wrap GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T
  owner 谁的图片
  need 文件是否必需
*/
bool LoadTextureJpg_4563E0(const char* filepath, int texId, int filter, int wrap, const char* owner, BOOL need)
{
	char pathBuf[260] = "Data\\";
	strcat(pathBuf, filepath);
	PathRenameExtension(pathBuf, ".OZJ");

	if (LoadTexture(pathBuf, texId, filter, wrap)) {
		return true;
	}
	else if (need) {
		MsgNoFile_exit(filepath, owner);
	}
	return false;
}

bool LoadTextureTga_456830(const char* filepath, int texId, int filter, int wrap, const char* owner, BOOL need)
{
	char pathBuf[260] = "Data\\";
	strcat(pathBuf, filepath);
	PathRenameExtension(pathBuf, ".OZT");

	if (LoadTexture(pathBuf, texId, filter, wrap)) {
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		return true;
	}
	else if (need) {
		MsgNoFile_exit(filepath, owner);
	}
	return false;
}
